package com.example.city_defense;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Color;

import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Graphics;
import com.badlogic.androidgames.framework.Input.TouchEvent;
import com.badlogic.androidgames.framework.Screen;

public class GameScreen extends Screen {

	enum GameState{
		Running,
		Paused,
		GameOver
	}
	
	enum game
	
	enum WeaponType{
		Basic,
		Extend,
		Ability
	}
	
	GameState state = GameState.Running;
	WeaponType weaType = WeaponType.Basic;
	
	World world;
	int oldScore = 0;
	String score = "0";
	int oldMoney = 0;
	String money = "0";
	boolean weaponSelected = false;
	
	public GameScreen(Game game, int difficultType, int mapType) {
		super(game);
		// TODO Auto-generated constructor stub
		world = new World(difficultType, mapType);
	}

	@Override
	public void update(float deltaTime) {
		// TODO Auto-generated method stub
		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
		game.getInput().getKeyEvents();
		
		if(state == GameState.Running){
			updateRunning(touchEvents, deltaTime);
		}
		if(state == GameState.Paused){
			updatePause(touchEvents);
		}
		if(state == GameState.GameOver){
			updateGameOver(touchEvents);
		}
		
	}

	public void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
		// TODO Auto-generated method stub
		 int len = touchEvents.size();
		 for(int i = 0; i < len; i++) { 
			 TouchEvent event = touchEvents.get(i);  
			 if(event.type == TouchEvent.TOUCH_UP) {  
				 if(event.x >= 650 && event.x <= 725) {
					 if(event.y >= 875 && event.y <= 950) {
						 if(Setting.soundEnable)
							 Asset.click.play(1);
						 state = GameState.Paused;
						 return; 
					 }
				 }
				 if(event.x >= 725 && event.x <= 800) {
					 if(event.y >= 875 && event.y <= 950) {
						 Setting.soundEnable = !Setting.soundEnable;
							if(Setting.soundEnable){
								Asset.click.play(1);
								Asset.main.play();
							}
							else
								Asset.main.stop();
						 return; 
					 }
				 }
				 
				 // Place weapon
				 if(event.x >= 0 && event.x <= 800) {
					 if(event.y >= 75 && event.y <= 875) {
						 if(Setting.soundEnable)
							 Asset.click.play(1);
						 if(weaponSelected == true){
							 world.weapon.get(world.weapon.size()-1).x = (event.x/50)*50;
							 world.weapon.get(world.weapon.size()-1).y = ((event.y-75)/50)*50+75;
							 world.weapon.get(world.weapon.size()-1).bullet.x = world.weapon.get(world.weapon.size()-1).x;
							 world.weapon.get(world.weapon.size()-1).bullet.y = world.weapon.get(world.weapon.size()-1).y;
							 weaponSelected = false;
						 }
						 return; 
					 }
				 }
				 
				 // Next attack...
				 if(event.x >= 0 && event.x <= 75) {
					 if(event.y >= 875 && event.y <= 950) {
						 if(Setting.soundEnable)
							Asset.click.play(1);	
						 	world.placeEnemy();
						 	world.nextAttack = true;
						 return; 
					 }
				 }
			 }    
			 if(event.type == TouchEvent.TOUCH_DRAGGED) {  
				 //...
			 }  
			 if(event.type == TouchEvent.TOUCH_DOWN) {  
				 
				 //Select Weapon Type...
				 if(event.x >= 0 && event.x <= 200) {
					 if(event.y >= 950 && event.y <= 1050) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 weaType = WeaponType.Basic;
						 return; 
					 }
				 }
				 if(event.x >= 0 && event.x <= 200) {
					 if(event.y >= 1050 && event.y <= 1150) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 weaType = WeaponType.Extend;
						 return; 
					 }
				 }
				 if(event.x >= 0 && event.x <= 200) {
					 if(event.y >= 1150 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 weaType = WeaponType.Ability;
						 return; 
					 }
				 }
				 
				 //Select weapon...
				 if(event.x >= 200 && event.x < 320) {
					 if(event.y >= 950 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 //...
						 if(weaType == WeaponType.Basic)
							 world.weapon.add(new Weapon(20, 20, 1));
						 else if(weaType == WeaponType.Extend)
							 world.weapon.add(new Weapon(20, 20, 6));
						 else if(weaType == WeaponType.Ability)
							 world.weapon.add(new Weapon(20, 20, 11));
						 weaponSelected = true;
						 return; 
					 }
				 }
				 if(event.x >= 320 && event.x < 440) {
					 if(event.y >= 950 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 //...
						 if(weaType == WeaponType.Basic)
							 world.weapon.add(new Weapon(20, 20, 2));
						 else if(weaType == WeaponType.Extend)
							 world.weapon.add(new Weapon(20, 20, 7));
						 else if(weaType == WeaponType.Ability)
							 world.weapon.add(new Weapon(20, 20, 12));
						 weaponSelected = true;
						 return; 
					 }
				 }
				 if(event.x >= 440 && event.x < 560) {
					 if(event.y >= 950 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 //...
						 if(weaType == WeaponType.Basic)
							 world.weapon.add(new Weapon(20, 20, 3));
						 else if(weaType == WeaponType.Extend)
							 world.weapon.add(new Weapon(20, 20, 8));
						 else if(weaType == WeaponType.Ability)
							 world.weapon.add(new Weapon(20, 20, 13));
						 weaponSelected = true;
						 return; 
					 }
				 }
				 if(event.x >= 560 && event.x < 680) {
					 if(event.y >= 950 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 //...
						 if(weaType == WeaponType.Basic)
							 world.weapon.add(new Weapon(20, 20, 4));
						 else if(weaType == WeaponType.Extend)
							 world.weapon.add(new Weapon(20, 20, 9));
						 else if(weaType == WeaponType.Ability)
							 world.weapon.add(new Weapon(20, 20, 14));
						 weaponSelected = true;
						 return; 
					 }
				 }
				 if(event.x >= 680 && event.x <= 800) {
					 if(event.y >= 950 && event.y <= 1250) {	
						 if(Setting.soundEnable){
							 Asset.click.play(1);
						 }
						 //...
						 if(weaType == WeaponType.Basic)
							 world.weapon.add(new Weapon(20, 20, 5));
						 else if(weaType == WeaponType.Extend)
							 world.weapon.add(new Weapon(20, 20, 10));
						 else if(weaType == WeaponType.Ability)
							 world.weapon.add(new Weapon(20, 20, 15));
						 weaponSelected = true;
						 return; 
					 }
				 }
			 }  
		       
		 }             
		 world.upDate(deltaTime);     
		 if(world.gameOver) {  
			 if(Setting.soundEnable)  
				 Asset.gameOver.play(1);     
			 state = GameState.GameOver;    
			 
		 } 
		 if(oldScore != world.score) {    
			 oldScore = world.score;   
			 score = "" + oldScore;   
			 if(Setting.soundEnable)  
				 Asset.boom.play(1);
		 }
		 if(oldMoney != world.money) {    
			 oldMoney = world.money;   
			 money = "" + oldMoney;   
			 
		 }
	}

	public void updatePause(List<TouchEvent> touchEvents) {
		// TODO Auto-generated method stub
		int len = touchEvents.size(); 
		for(int i = 0; i < len; i++) {  
			TouchEvent event = touchEvents.get(i);  
			if(event.type == TouchEvent.TOUCH_UP) {  
				if(event.x >= 190 && event.x <= 615) {
					if(event.y >= 630 && event.y <= 660) {  
						if(Setting.soundEnable) 
							Asset.click.play(1);
						state = GameState.Running;  
						return; 
					}
				}
				if(event.x >= 330 && event.x <= 470) {
					if(event.y >= 690 && event.y <= 720) {  
						if(Setting.soundEnable) 
							Asset.gameOver.play(1);
						state = GameState.GameOver;  
						return; 
					}
				}
			}            	   
		}
	}
	
	public void updateGameOver(List<TouchEvent> touchEvents) {
		// TODO Auto-generated method stub
		int len = touchEvents.size(); 
		for(int i = 0; i < len; i++) {  
			TouchEvent event = touchEvents.get(i);  
			if(event.type == TouchEvent.TOUCH_UP) {  
				if(event.x >= 362 && event.x <= 437) {
					if(event.y >= 600 && event.y <= 675) {  
						if(Setting.soundEnable) 
							Asset.click.play(1);
						game.setScreen(new MainMenuScreen(game));  
						return; 
					}
				}
			}            	   
		}
	}

	@Override
	public void present(float deltaTime) {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		
		drawWorld(world);
		if(state == GameState.Running){
			drawRunningUI();
		}
		if(state == GameState.Paused){
			drawPauseUI();
		}
		if(state == GameState.GameOver){
			drawGameOverUI();
		}
		
		drawText(g, score, 660, 13); 
		drawText(g, money, 90, 13); 
	}

	public void drawWorld(World world) {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		
		g.drawBackground(Color.GRAY);
		g.drawPixmap(Asset.button, 0, 0, 75, 150,75,75);
		g.drawPixmap(Asset.score, 540, 15);
		if(world.map.mapTYPE == 0)
			g.drawPixmap(Asset.map1, 0,75);
		else if(world.map.mapTYPE == 1)
			g.drawPixmap(Asset.map2, 0,75);
		else if(world.map.mapTYPE == 2)
			g.drawPixmap(Asset.map3, 0,75);
		
		ArrayList<Weapon> weapon = new ArrayList<Weapon>();
		ArrayList<Enemy> enemy = new ArrayList<Enemy>();
		
		// Enemy and Weapon,...
		for (int i = 0; i < world.weapon.size(); i++) {
			weapon.add(world.weapon.get(i));
		}
		for (int i = 0; i < world.enemy.size(); i++) {
			enemy.add(world.enemy.get(i));
		}
		
		/*Pixmap weaponPixmap = weapon.pixmap;
		Pixmap enemyPixmap = enemy.pixmap;
		Pixmap bulletPixmap = bullet.pixmap;*/
		
		/*int enemyX = enemy.x;
		int enemyY = enemy.y;
		int weaponX = weapon.x;
		int weaponY = weapon.y;
		int bulletX = bullet.x;
		int bulletY = bullet.y;*/
		
		//g.drawPixmap(weaponPixmap, weaponX, weaponY);
		/*if(weapon.get(i).boom){
		g.drawPixmap(Asset.bang, enemyX, enemyY);
		world.score += enemy.point;
		world.money += enemy.coinGain;
		weapon.boom = false;
		}*/
		/*if(bullet.isAlive)
		g.drawPixmap(bulletPixmap, bulletX, bulletY);
		if(enemy.isAlive){
			if(enemy.DIRECTION == 0)
				g.drawPixmap(enemyPixmap, enemyX, enemyY, 0, 0, 37, 50);
			else if(enemy.DIRECTION == 1)
				g.drawPixmap(enemyPixmap, enemyX, enemyY, 50, 0, 50, 37);
			else if(enemy.DIRECTION == 2)
				g.drawPixmap(enemyPixmap, enemyX, enemyY, 0, 50, 37, 50);
			else if(enemy.DIRECTION == 3)
				g.drawPixmap(enemyPixmap, enemyX, enemyY, 50, 50, 50, 37);
			g.drawRect(enemyX, enemyY - 15, 50, 5, Color.BLACK);
			if(enemy.blood <= (enemy.blood+enemy.damage)/3)
				g.drawRect(enemyX, enemyY - 15, enemy.blood*50/(enemy.damage+ enemy.blood), 5, Color.RED);
			else 
				g.drawRect(enemyX, enemyY - 15, enemy.blood*50/(enemy.damage+ enemy.blood), 5, Color.GREEN);
		}
		*/
		for (int i = 0; i < weapon.size(); i++) {
			g.drawPixmap(weapon.get(i).pixmap, weapon.get(i).x, weapon.get(i).y);
			
			for (int j = 0; j < enemy.size(); j++) {
				if(weapon.get(i).boom){
					g.drawPixmap(Asset.bang, enemy.get(j).x, enemy.get(j).y);
					world.score += enemy.get(j).point;
					world.money += enemy.get(j).coinGain;
					weapon.get(i).boom = false;
				}
				
			}
			
		}
		for (int i = 0; i < weapon.size(); i++) {
			if(weapon.get(i).bullet.isAlive){
				g.drawPixmap(weapon.get(i).bullet.pixmap, weapon.get(i).bullet.x, weapon.get(i).bullet.y);
			}
		}
		
		for (int i = 0; i < enemy.size(); i++) {
			
			if(enemy.get(i).isAlive){
				if(enemy.get(i).DIRECTION == 0)
					g.drawPixmap(enemy.get(i).pixmap, enemy.get(i).x, enemy.get(i).y, 0, 0, 37, 50);
				else if(enemy.get(i).DIRECTION == 1)
					g.drawPixmap(enemy.get(i).pixmap, enemy.get(i).x, enemy.get(i).y, 50, 0, 50, 37);
				else if(enemy.get(i).DIRECTION == 2)
					g.drawPixmap(enemy.get(i).pixmap, enemy.get(i).x, enemy.get(i).y, 0, 50, 37, 50);
				else if(enemy.get(i).DIRECTION == 3)
					g.drawPixmap(enemy.get(i).pixmap, enemy.get(i).x, enemy.get(i).y, 50, 50, 50, 37);
				g.drawRect(enemy.get(i).x, enemy.get(i).y - 15, 50, 5, Color.BLACK);
				if(enemy.get(i).blood <= (enemy.get(i).blood+enemy.get(i).damage)/3)
					g.drawRect(enemy.get(i).x, enemy.get(i).y - 15, enemy.get(i).blood*50/(enemy.get(i).damage+ enemy.get(i).blood), 5, Color.RED);
				else 
					g.drawRect(enemy.get(i).x, enemy.get(i).y - 15, enemy.get(i).blood*50/(enemy.get(i).damage+ enemy.get(i).blood), 5, Color.GREEN);
			}
		
		}
		
	}
	
	public void drawGrid() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		for (int i = 0; i <= 16; i++) {
			g.drawLine(i*50, 75, i*50, 875, Color.GREEN);
			g.drawLine(0, i*50+75, 800, i*50+75, Color.GREEN);
		}
		
	}

	public void drawAbilityWeapon() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		g.drawPixmap(Asset.ability1, 235, 985);
		g.drawPixmap(Asset.ability1, 355, 985);
		g.drawPixmap(Asset.ability1, 475, 985);
		g.drawPixmap(Asset.ability1, 595, 985);
		g.drawPixmap(Asset.ability1, 715, 985);
	}

	public void drawExtendWeapon() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		g.drawPixmap(Asset.extend1, 235, 985);
		g.drawPixmap(Asset.extend1, 355, 985);
		g.drawPixmap(Asset.extend1, 475, 985);
		g.drawPixmap(Asset.extend1, 595, 985);
		g.drawPixmap(Asset.extend1, 715, 985);
	}

	public void drawBasicWeapon() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		g.drawPixmap(Asset.basic1, 235, 985);
		g.drawPixmap(Asset.basic1, 355, 985);
		g.drawPixmap(Asset.basic1, 475, 985);
		g.drawPixmap(Asset.basic1, 595, 985);
		g.drawPixmap(Asset.basic1, 715, 985);
	}
	
	public void drawRunningUI() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		
		g.drawPixmap(Asset.button, 0, 875, 150, 150, 75, 75);
		g.drawPixmap(Asset.button, 75, 875, 225, 150, 61, 75);
		g.drawPixmap(Asset.people, 450, 875);
		g.drawPixmap(Asset.button, 650, 875, 75, 0, 75, 75);
		if(Setting.soundEnable)
			g.drawPixmap(Asset.button, 725, 875, 0, 75, 75, 75);
		else
			g.drawPixmap(Asset.button, 725, 875, 75, 75, 75, 75);
		g.drawPixmap(Asset.select_weapon, 0, 950);
		g.drawPixmap(Asset.weapon_slot, 200, 950);	
		if(weaType == WeaponType.Basic){
			drawBasicWeapon();
		}
		if(weaType == WeaponType.Extend){
			drawExtendWeapon();
		}
		if(weaType == WeaponType.Ability){
			drawAbilityWeapon();
		}
		if(weaponSelected){
			drawGrid();
		}
		
	}
	
	public void drawPauseUI() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		g.drawPixmap(Asset.pause_background, 150, 400);
	}
	
	public void drawGameOverUI() {
		// TODO Auto-generated method stub
		Graphics g = game.getGraphics();
		
		g.drawPixmap(Asset.gameover, 223, 500);
		g.drawPixmap(Asset.button, 362, 600, 225, 0, 75, 75);
	}

	public void drawText(Graphics g, String line, int x, int y) {  
		int len = line.length();  
		for (int i = 0; i < len; i++) {  
			char character = line.charAt(i);      
			if (character == ' ') {   
				x += 31;          
				continue;     	
			}                 
			int srcX = 0;     
			int srcWidth = 0;    
			if (character == '.') {    
				srcX = 310;     
				srcWidth = 16;     	
			} else {  
				srcX = (character - '0') * 31;  
				srcWidth = 31;       	
			}                
			g.drawPixmap(Asset.number, x, y, srcX, 0, srcWidth, 50);   
			x += srcWidth;    
			
		}
		
	}
	
	@Override
	public void pause() {
		// TODO Auto-generated method stub
		if(state == GameState.Running){
			state = GameState.Paused;
		}
		
		if(state == GameState.GameOver){
			Setting.addScore(world.score);
			//Setting.addMoney...
			Setting.save(game.getFileIO());
		}
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub

	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

}